package com.avecsys.quotemanager.service.supplier;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.avecsys.quotemanager.dao.common.EnumDBRecordStatus;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.dao.supplier.SupplierMasterDAO;
import com.avecsys.quotemanager.dao.user.UserMasterDAO;
import com.avecsys.quotemanager.exception.BusinessException;
import com.avecsys.quotemanager.exception.DAOException;
import com.avecsys.quotemanager.pojos.SupplierMasterPojo;
import com.avecsys.quotemanager.pojos.UserMasterPojo;
import com.avecsys.quotemanager.utils.TransactionStatus;

/**
 * 
 * @author Sam Sundar K
 * 
 */
public class SupplierMasterServiceImpl implements SupplierMasterService {

	private static final Log log = LogFactory
			.getLog(SupplierMasterServiceImpl.class);

	private SupplierMasterDAO supplierMasterDAO;

	private UserMasterDAO userMasterDAO;

	/**
	 * @return the userMasterDAO
	 */
	public UserMasterDAO getUserMasterDAO() {
		return userMasterDAO;
	}

	/**
	 * @param userMasterDAO
	 *            the userMasterDAO to set
	 */
	public void setUserMasterDAO(UserMasterDAO userMasterDAO) {
		this.userMasterDAO = userMasterDAO;
	}

	/**
	 * @return the supplierMasterDAO
	 */
	public SupplierMasterDAO getSupplierMasterDAO() {
		return supplierMasterDAO;
	}

	/**
	 * @param supplierMasterDAO
	 *            the supplierMasterDAO to set
	 */
	public void setSupplierMasterDAO(SupplierMasterDAO supplierMasterDAO) {
		this.supplierMasterDAO = supplierMasterDAO;
	}

	/**
	 * Method to save or update the supplier master information with default
	 * administrator user
	 * 
	 * @param supplierMasterPojo
	 * @return Integer
	 * @throws BusinessException
	 */
	public TransactionStatus saveSupplierMaster(
			SupplierMasterPojo supplierMasterPojo) throws BusinessException {
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.FAIL.ordinal());
		try {
			/*
			 * if (!isSupplierEmailNotRegistered(supplierMasterPojo)) {
			 * transactionStatus
			 * .setStatus(EnumTransactionStatus.BUSINESS_FLOW_FAIL .ordinal());
			 * transactionStatus.setErrorFieldName("emailId"); }
			 */
			// Step1:
			// if the Supplier Master information already persisted then update
			// other wise create a new supplier information with default use
			// Mark As Active
			supplierMasterPojo.setStatus(EnumDBRecordStatus.ACTIVE.status());
			if (supplierMasterPojo.isPersisted()) {
				// Check default Administrator is avaiable
				List<UserMasterPojo> userMasterPojoList = userMasterDAO
						.findAllSupplierAdminUsers(supplierMasterPojo);
				if (userMasterPojoList == null
						|| userMasterPojoList.size() == 0) {
					UserMasterPojo userMasterPojo = createDefaultAdminInstance(supplierMasterPojo);
					supplierMasterPojo.getSupplierUsers().add(userMasterPojo);
				}
				transactionStatus.setStatus(supplierMasterDAO
						.update(supplierMasterPojo));
			} else {
				// Check Email Address not registered with another Supplier

				// Create New Supplier With Default Administrator
				UserMasterPojo userMasterPojo = createDefaultAdminInstance(supplierMasterPojo);
				supplierMasterPojo.getSupplierUsers().add(userMasterPojo);
				transactionStatus.setStatus(supplierMasterDAO
						.save(supplierMasterPojo));
			}
		} catch (DAOException e) {
			log.error(e);
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * @param supplierMasterPojo
	 * @return
	 */
	private UserMasterPojo createDefaultAdminInstance(
			SupplierMasterPojo supplierMasterPojo) {
		UserMasterPojo userMasterPojo = new UserMasterPojo();
		userMasterPojo.setSupplierMasterPojo(supplierMasterPojo);
		userMasterPojo.setUserName("Admin");
		userMasterPojo.setPassword("password");
		userMasterPojo.setIsAdmin(Boolean.TRUE.toString());
		userMasterPojo.setEmail(supplierMasterPojo.getEmail());
		userMasterPojo.setStatus(EnumDBRecordStatus.ACTIVE.status());
		return userMasterPojo;
	}

	/**
	 * Method to return all the suppliers
	 * 
	 * @return List<SupplierMasterPojo>
	 */
	@Override
	public List<SupplierMasterPojo> getAllSuppliers() throws BusinessException {
		try {
			return supplierMasterDAO.findAllActive(new SupplierMasterPojo());
		} catch (DAOException e) {
			throw new BusinessException(e);
		}
	}

	/**
	 * Method to delete the supplier master information by supplier id
	 * 
	 * @param supplierId
	 * @return Integer value of transaction status
	 * @throws BusinessException
	 */
	public Integer deleteSupplierMasterById(Long supplierId)
			throws BusinessException {
		Integer transactionStatus = EnumTransactionStatus.FAIL.ordinal();
		try {
			SupplierMasterPojo supplierMasterPojo = new SupplierMasterPojo();
			supplierMasterPojo = supplierMasterDAO.findById(supplierMasterPojo,
					supplierId);
			transactionStatus = supplierMasterDAO
					.markAsDeleted(supplierMasterPojo);
		} catch (DAOException e) {
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to get the supplier master information by supplier id
	 * 
	 * @param supplierId
	 * @return SupplierMasterPojo instance
	 * @throws BusinessException
	 */
	@Override
	public SupplierMasterPojo getSupplierMasterById(Long supplierId)
			throws BusinessException {
		SupplierMasterPojo supplierMasterPojo = new SupplierMasterPojo();
		try {
			supplierMasterPojo = supplierMasterDAO.findById(supplierMasterPojo,
					supplierId);
		} catch (DAOException e) {
			throw new BusinessException(e);
		}
		return supplierMasterPojo;
	}

	@Override
	public List<UserMasterPojo> getAllUsers(
			SupplierMasterPojo supplierMasterPojo) throws BusinessException {
		try {
			return userMasterDAO.findAllUsersBySupplier(supplierMasterPojo);
		} catch (DAOException e) {
			throw new BusinessException(e);
		}
	}

	/**
	 * Method to verify the supplier email is not registered with another
	 * supplier
	 * 
	 * @param supplierMasterPojo
	 * @param email
	 * @return boolean
	 * @throws DAOException
	 */
	public boolean isSupplierEmailNotRegistered(
			SupplierMasterPojo supplierMasterPojo) throws DAOException {
		boolean isValid = true;
		Map<String, Object> criteria = new HashMap<String, Object>();
		criteria.put("email", supplierMasterPojo.getEmail());
		List<SupplierMasterPojo> supplierMasterPojoList = supplierMasterDAO
				.findAllActiveByCriteria(supplierMasterPojo, criteria);
		if (supplierMasterPojoList.size() > 0) {
			SupplierMasterPojo tmpSupplierMasterPojo = supplierMasterPojoList
					.get(0);
			// If Existing Supplier update case
			if (supplierMasterPojo.isPersisted()) {
				// If another supplier object then compare both email
				if (!tmpSupplierMasterPojo.getSupplierId().equals(
						supplierMasterPojo.getSupplierId())) {
					if (tmpSupplierMasterPojo.getEmail().equalsIgnoreCase(
							supplierMasterPojo.getEmail())) {
						isValid = false;
					}
				}
			} else {
				// New Supplier creation Case
				if (tmpSupplierMasterPojo.getEmail().equalsIgnoreCase(
						supplierMasterPojo.getEmail())) {
					isValid = false;
				}
			}
		}
		return isValid;
	}
}
